package com.spring.boot.utils;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.spring.boot.vo.ProvinceVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.selector.Selectable;


import static com.spring.boot.utils.MyUtils.*;


@Component
public class MyProcessor implements PageProcessor {
    private final static Logger log = LoggerFactory.getLogger(MyProcessor.class);

    @Autowired
    private MyPipline myPipline;
    // 部分一：抓取网站的相关配置，包括编码、抓取间隔、重试次数等
    private final Site site = Site.me().setRetryTimes(3).setSleepTime(1000);

    @Override
    public Site getSite() {
        return site;
    }


    @Override
    // process是定制爬虫逻辑的核心接口，在这里编写抽取逻辑
    public void process(Page page) {
        //todo 这个process的代码冗余
        String url = page.getUrl().toString();
        //对不同站点的抓取到的页面做判断
        if (url.equals("https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner&city=%E7%A6%8F%E5%BB%BA-%E7%A6%8F%E5%BB%BA")) {
            // 部分二：定义如何抽取页面信息，并保存下来
            Selectable nodes = page.getHtml().css("script#captain-config");
            String nodesStr = nodes.get();
            String substring = nodesStr.substring(52, nodesStr.length() - 9);
            JSONObject jsonObject = JSONObject.parseObject(substring);//这个页面的所有信息
            JSONArray component = jsonObject.getJSONArray("component");
            JSONObject component0 = JSONObject.parseObject(component.get(0).toString());
            JSONArray caseList = component0.getJSONArray("caseList");
            ProvinceVo provinceVo = JSONObject.parseObject(caseList.get(20).toString(), ProvinceVo.class);
            page.putField("provinceVo", provinceVo);
            page.putField("citys", provinceVo.getSubList());
            System.out.println(provinceVo.toString());
            page.putField("chinaCaseList", caseList);
        } else if (url.contains("move_in") && url.contains("cityrank")) {
            String rawText = page.getRawText();
            String replace = StringUtils.replace(rawText, "cb(", "");
            String replace1 = replace.replace(")", "");
            //todo 这里json对象转java对象操作是在pipeline进行的。后续应该统一一下。
            JSONObject parse = JSON.parseObject(replace1);
            String errmsg = String.valueOf(parse.get("errmsg"));
            if (errmsg.equals("SUCCESS")) {
                JSONObject data = JSONObject.parseObject(parse.get("data").toString());
                JSONArray list = JSONArray.parseArray(data.get("list").toString());
                page.putField("inOutNum", list);
                page.putField("type", "in");
                String cityId = StrUtil.sub(url, 61, 67);
                CityId city = CityId.getCityById(cityId);
                page.putField("originCity", city);
            }
            log.info(String.valueOf(parse));
        } else if (url.contains("move_out") && url.contains("cityrank")) {
            String rawText = page.getRawText();
            String replace = StringUtils.replace(rawText, "cb(", "");
            String replace1 = replace.replace(")", "");
            //todo 这里json对象转java对象操作是在pipeline进行的。后续应该统一一下。
            JSONObject parse = JSON.parseObject(replace1);
            String errmsg = String.valueOf(parse.get("errmsg"));
            if (errmsg.equals("SUCCESS")) {
                JSONObject data = JSONObject.parseObject(parse.get("data").toString());
                JSONArray list = JSONArray.parseArray(data.get("list").toString());
                page.putField("inOutNum", list);
                page.putField("type", "out");
                String cityId = StrUtil.sub(url, 61, 67);
                CityId city = CityId.getCityById(cityId);
                page.putField("originCity", city);
            }
            log.info(String.valueOf(parse));
        } else if (url.contains("move_out") && url.contains("historycurve")) {
            String rawText = page.getRawText();
            String replace = StringUtils.replace(rawText, "cb(", "");
            String replace1 = replace.replace(")", "");
            //todo 这里json对象转java对象操作是在pipeline进行的。后续应该统一一下。
            JSONObject parse = JSON.parseObject(replace1);
            String errmsg = String.valueOf(parse.get("errmsg"));
            if (errmsg.equals("SUCCESS")) {
                JSONObject data = JSONObject.parseObject(parse.get("data").toString());
                JSONObject list = JSONObject.parseObject(data.get("list").toString());
                page.putField("historyCurve", list);
                page.putField("type", "out");
                String cityId = StrUtil.sub(url, 65, 71);
                CityId city = CityId.getCityById(cityId);
                page.putField("originCity", city);
            }
            log.info(String.valueOf(parse));
        } else if (url.contains("move_in") && url.contains("historycurve")) {
            String rawText = page.getRawText();
            String replace = StringUtils.replace(rawText, "cb(", "");
            String replace1 = replace.replace(")", "");
            //todo 这里json对象转java对象操作是在pipeline进行的。后续应该统一一下。
            JSONObject parse = JSON.parseObject(replace1);
            String errmsg = String.valueOf(parse.get("errmsg"));
            if (errmsg.equals("SUCCESS")) {
                JSONObject data = JSONObject.parseObject(parse.get("data").toString());
                JSONObject list = JSONObject.parseObject(data.get("list").toString());
                page.putField("historyCurve", list);
                page.putField("type", "in");
                String cityId = StrUtil.sub(url, 65, 71);
                CityId city = CityId.getCityById(cityId);
                page.putField("originCity", city);
            }
            log.info(String.valueOf(parse));
        }
    }


    private final String url = "https://huiyan.baidu.com/migration/cityrank.jsonp?dt=city";
    private final String url2 = "https://huiyan.baidu.com/migration/historycurve.jsonp?dt=city";
    int a = 0;
    boolean isIn = true;

//todo 应该多开几个url，一个url一个线程，这样数据才入库得快。
    @Scheduled(initialDelay = 3000, fixedDelay = 3000)
    public void process() {
        String cityRankUrl = url + "&id=" + CityId.class.getEnumConstants()[a].getId().toString() + "&type=" + getInOutStr(isIn) + "&date=" + getYesterday();
//        String cityRankUrl = url + "&id=" + CityId.class.getEnumConstants()[a].getId().toString() + "&type=" + getInOutStr(isIn) + "&date=20220227";
        String historyCurveUrl = url2 + "&id=" + CityId.class.getEnumConstants()[a].getId().toString() + "&type=" + getInOutStr(isIn);
        Spider spider = Spider.create(new MyProcessor());
        spider
                .addUrl("https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_aladin_banner&city=%E7%A6%8F%E5%BB%BA-%E7%A6%8F%E5%BB%BA")
                .addUrl(cityRankUrl)
                .addUrl(historyCurveUrl)
//                使用pipeline保存到数据库
                .addPipeline(myPipline)
                //开启3个线程抓取
                .thread(3)
                //启动爬虫
                .run();
        int i = ++a;
        if (i > 8) {
            a = 0;
        }
        isIn = !isIn;
        System.out.println("process启动次数=》" + i);
//        监控爬虫。在终端输入 jconsole.exe
//        SpiderMonitor.instance().register(spider);
    }


}
